package com.crm.jpaandthymeleaf.service.impl;

import com.crm.jpaandthymeleaf.service.LockLoginService;
import com.crm.jpaandthymeleaf.web.exception.LoginException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * 使用Redis作为登录锁定的控制服务
 *
 * @author 周敬
 * @version 1.0
 * @packageName com.crm.jpaandthymeleaf.service.impl
 * @fileName LockLoginServiceImpl
 * @createTime 2021/12/30-8:45-星期四
 * @lastModify 2021/12/30-8:45-星期四
 */
@Service
public class LockLoginServiceImpl implements LockLoginService {

    /**
     * 尝试次数
     */
    @Value("${redis.try.count}")
    private int tryCount;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 检查用户是否能登录
     *
     * @param usrName
     * @throws LoginException
     */
    @Override
    public void checkLogin(String usrName) throws LoginException {
        String key = SHIRO_LOGIN_COUNT + usrName;
        ValueOperations<String, String> ops = stringRedisTemplate.opsForValue();
        //在原本的基础上进行加一操作
        ops.increment(key);
        //设置一个小时的失效时间
        stringRedisTemplate.expire(key,1,TimeUnit.HOURS);
        //获取尝试次数
        Integer loginCount = Integer.parseInt(ops.get(key));
        if (loginCount >= tryCount) {
            throw new LoginException("登录次数达到了：" + loginCount + "次了");
        }
    }

    /**
     * 锁定用户
     *
     * @param usrName
     */
    @Override
    public void lock(String usrName) {
        String key = SHIRO_IS_LOCK + usrName;
        ValueOperations<String, String> ops = stringRedisTemplate.opsForValue();
        ops.set(key, SHIRO_LOCK_VALUE, 1, TimeUnit.HOURS);
        //清除登录记录
        clean(usrName);
    }

    /**
     * 判断LOCK是否已经被锁定
     *
     * @param usrName
     * @return
     */
    @Override
    public boolean isLock(String usrName) {
        String key = SHIRO_IS_LOCK + usrName;
        ValueOperations<String, String> ops = stringRedisTemplate.opsForValue();
        if (SHIRO_LOCK_VALUE.equalsIgnoreCase(ops.get(key))) {
            return true;
        }
        return false;
    }

    /**
     * 解锁用户
     *
     * @param usrName
     */
    @Override
    public void unLock(String usrName) {
        String key = SHIRO_IS_LOCK + usrName;
        stringRedisTemplate.delete(key);
    }

    /**
     * 清空登录记录
     *
     * @param usrName
     */
    @Override
    public void clean(String usrName) {
        String key = SHIRO_LOGIN_COUNT + usrName;
        stringRedisTemplate.delete(key);
    }
}
